

#ifndef SIENAINTERFACE_H_
#define SIENAINTERFACE_H_


#include "../Packets/PubPkt.h"
#include "../Packets/BackSubPkt.h"
#include <set>
#include <boost/unordered_map.hpp>
#include "sff/fwd_table.h"
#include "sff/simple_handler.h"
#include "sff/simple_fwd_types.h"
#include "sff/siena/forwarding.h"
#include <iostream>
#include "../Common/Consts.h"
#include "SubscriptionManager.h"


class SienaInterface : public SubscriptionManager {

public:

	SienaInterface();

	virtual ~SienaInterface();

	void installSubscription(Inbox* parInbox);

	void deleteSubscription(Inbox* parInbox);

	void processEvent(PubPkt* pkt, Outbox &outbox);

	void test();

	void buildForwardingTable();

private:

	class SienaOutputInterface : public siena::MatchHandler {
		std::set<int> matchedClients;
	public:
		SienaOutputInterface() {}
	    virtual	~SienaOutputInterface() {}
	    bool output(if_t ifId) throw();
	    void clear();
		std::set<int> getMatchedClients() { return matchedClients; }
	};

	siena::FwdTable *fwdTable;
	SienaOutputInterface outputInterface;

	boost::unordered_map<BackSubPkt*, simple_filter*> subscriptionToFilterMap;
	//boost::unordered_map<if_t, std::set<simple_filter *> > sienaForwardingMap;
	boost::unordered_map<if_t, simple_predicate *> newsienaForwardingMap;

	simple_filter* translate(BackSubPkt* pkt);
	simple_message* translate(PubPkt* pkt);

	pthread_t *buildingThread;
	pthread_mutex_t *buildingTableMutex;
	pthread_cond_t *buildingTableCond;
	bool onBuilding;
	bool toBuild;

};

namespace siena_interface {

void * startBuildForwardingTable(void *input);

};


#endif /* SIENAINTERFACE_H_ */
